package wsepForum.network.server.gate;

import java.util.Collection;
import java.util.Date;

import wsepForum.common.elements.Message;
import wsepForum.common.elements.User.UserType;
import wsepForum.domain.Session;
import wsepForum.domain.handlers.AUserHandler;
import wsepForum.domain.handlers.MemberHandler;
import wsepForum.network.common.GUIAnswer;
import wsepForum.network.common.GUIRequest;

/**
 * makes GUIRequests to requests at session handlers
 * @author Oren Ben-Haim & Amir Harel
 *
 */
public class GUIRequestHandler {

	/*****************************
	 * MEMBERS                   *
	 *****************************/
	/**
	 * Parses GUIRequests to requests at session handlers
	 * @param request GUIRequest to parse
	 * @param session the session were handling
	 * @return GUIAnswer- returned answer from session's handler
	 */
	@SuppressWarnings("unchecked")
	public static GUIAnswer handleRequest(GUIRequest request, Session session) {
		Object[] args = request.getArguments();
		int sequence = request.getSequenceID();
		try {
			switch (request.getRequestType()) {

			case ADD_MOD_TO_SECTION:
				return runAddModeratorToSection((Integer)args[0],(String)args[1],session,sequence);

			case CREATE_SECTION:
				return runCreateSection((Integer)args[0],(String)args[1],(Collection<String>)args[2],session,sequence);

			case DELETE_MESSAGE:
				return runDeleteMessage((Integer)args[0],(Integer)args[1],session,sequence);

			case EDIT_MESSAGE:
				return runEditMessage((Integer)args[0],(Integer)args[1],(String)args[2],(String)args[3], session,sequence);

			case ADD_TO_TOPIC:
				return runAddMessageToTopic((Integer)args[0],(String)args[1],(String)args[2],session,sequence);

			case CREATE_TOPIC:
				return runCreateTopic((Integer)args[0],(String)args[1],(String)args[2],session,sequence);

			case GET_MESSAGE:
				return runGetMsg((Integer) args[0],session,sequence);

			case GET_SETCION:
				return runGetSection((Integer) args[0],session,sequence);

			case GET_TOPIC:
				return runGetTopic((Integer) args[0],session,sequence);

			case LOGIN:
				return runLogin((String)args[0],(String)args[1],session,sequence);

			case LOGOUT:
				return runLogout(session,sequence);

			case REGISTER:
				return runRegister((String)args[0],(String)args[1],session,sequence);

			case REMOVE_MOD:
				return runRemoveModeratorFromSection((Integer)args[0],(String)args[1],session,sequence);

			case REMOVE_SECTION:
				return runRemoveSection((Integer)args[0],session,sequence);

			case REMOVE_USER:
				return runRemoveUser((String)args[0],session,sequence);

			case SEARCH_BY_AUTHOR:
				return runSearchByAuthor((String)args[0],session,sequence);

			case SEARCH_BY_CONTENT:
				return runSearchByContent((String)args[0],session,sequence);

			case SEARCH_BY_DATES:
				return runSearchByDate((Date)args[0],(Date)args[1],session,sequence);
				
			case GET_USER_LIST:
				return runGetUserList(session,sequence);
			
			case GET_MNG_USER_LIST:
				return runGetMngUserList(session,sequence);
				
			case CHNG_PASS:
				return runChngPassword((String)args[0],(String)args[1],session,sequence);
				
			}
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] {e},sequence, session.getHandler().getNumOfUsers());
		}
		return null;
	}


	private static GUIAnswer runLogin(String username, String password, Session session, int sequence) {
		try {
			boolean loginAns = session.login(username, password);
			UserType type = UserType.MEMBER;
			if (loginAns) {
				type = ((MemberHandler)session.getHandler()).getUser().getUserType();
			}
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { loginAns, type },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runLogout(Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.logout() },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runRegister(String username, String password, Session session, int sequence) {
			try {
				return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().register(username, password) },sequence, session.getHandler().getNumOfUsers());
			} catch (Exception e) {
				return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
			}
	}

	private static GUIAnswer runCreateTopic(int sectionID, String headline, String body, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().createTopic(sectionID, headline , body) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runGetMsg(int messageID, Session session, int sequence) {

		try {
			AUserHandler handler = session.getHandler();
			// The requested message
			Message msg = handler.getMessage(messageID);
			int sectionID = (handler.getTopic(msg.getParentID())).getParentID();
			boolean editAuth = handler.editMessageAuthentication(msg, sectionID);
			boolean deleteAuth = handler.deleteMessageAuthentication(msg, sectionID);
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { msg, editAuth, deleteAuth },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runGetSection(int sectionID, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().getSection(sectionID), session.getHandler().editSectionAuthentication() },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runGetTopic(int topicID, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().getTopic(topicID) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runAddMessageToTopic(int topicID, String headline, String body, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().addMessageToTopic(topicID, headline , body) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runEditMessage(int topicID, int messageToEditID, String headline, String body, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().editMessage(topicID, messageToEditID, headline , body) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runDeleteMessage(int parentTopicID, int messageToDeleteID, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().deleteMessage(parentTopicID, messageToDeleteID), session.getHandler().editSectionAuthentication()}, sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runCreateSection(int parentSectionID, String sectionName, Collection<String> moderators, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().createSection(parentSectionID, sectionName, moderators),session.getHandler().editSectionAuthentication()} ,sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runAddModeratorToSection(int sectionID, String userName, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().addModeratorToSection(sectionID, userName) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runRemoveSection(int sectionID, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().removeSection(sectionID) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runRemoveModeratorFromSection(int sectionID, String userName, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().removeModerator(sectionID, userName) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runRemoveUser(String userName, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().removeUser(userName) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runSearchByAuthor(String authorName, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().searchByAuthor(authorName) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runSearchByDate(Date from, Date to, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().searchByDate(from, to) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

	private static GUIAnswer runSearchByContent(String sentence, Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().searchByContent(sentence) },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}
	
	private static GUIAnswer runGetMngUserList(Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().getManagedUsernames() },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}
	
	private static GUIAnswer runChngPassword(String oldPassword, String newPassword, Session session, int sequence){
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] {session.getHandler().changePassword(oldPassword, newPassword)},sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}
	
	private static GUIAnswer runGetUserList(Session session, int sequence) {
		try {
			return new GUIAnswer(GUIAnswer.AnswerType.ANSWER, new Object[] { session.getHandler().getAllUsernames() },sequence, session.getHandler().getNumOfUsers());
		} catch (Exception e) {
			return new GUIAnswer(GUIAnswer.AnswerType.EXCEPTION, new Object[] { e },sequence, session.getHandler().getNumOfUsers());
		}
	}

}
